package com.zenithmind.document.pojo.dto;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;

import jakarta.validation.constraints.Min;
import java.time.LocalDateTime;

/**
 * 文档统计更新DTO
 * 遵循单一职责原则：专注于统计更新数据传输
 * 遵循开闭原则：支持字段的扩展
 * 
 * @author ZenithMind Team
 * @since 2025-01-09
 */
@Data
@Schema(description = "文档统计更新DTO")
public class DocumentStatisticsUpdateDTO {

    @Schema(description = "查看次数", example = "150")
    @Min(value = 0, message = "查看次数不能为负数")
    private Long viewCount;

    @Schema(description = "下载次数", example = "35")
    @Min(value = 0, message = "下载次数不能为负数")
    private Long downloadCount;

    @Schema(description = "分享次数", example = "18")
    @Min(value = 0, message = "分享次数不能为负数")
    private Long shareCount;

    @Schema(description = "收藏次数", example = "22")
    @Min(value = 0, message = "收藏次数不能为负数")
    private Long favoriteCount;

    @Schema(description = "评论次数", example = "12")
    @Min(value = 0, message = "评论次数不能为负数")
    private Long commentCount;

    @Schema(description = "点赞次数", example = "28")
    @Min(value = 0, message = "点赞次数不能为负数")
    private Long likeCount;

    @Schema(description = "评分次数", example = "16")
    @Min(value = 0, message = "评分次数不能为负数")
    private Long ratingCount;

    @Schema(description = "平均评分", example = "4.3")
    private Double averageRating;

    @Schema(description = "总评分", example = "68.8")
    private Double totalRating;

    @Schema(description = "独立访客数", example = "95")
    @Min(value = 0, message = "独立访客数不能为负数")
    private Long uniqueVisitors;

    @Schema(description = "总访问时长（秒）", example = "4500")
    @Min(value = 0, message = "总访问时长不能为负数")
    private Long totalViewDuration;

    @Schema(description = "平均访问时长（秒）", example = "135")
    private Double averageViewDuration;

    @Schema(description = "跳出率", example = "0.22")
    private Double bounceRate;

    @Schema(description = "转化率", example = "0.18")
    private Double conversionRate;

    @Schema(description = "最后查看时间", example = "2025-01-09T16:30:00")
    private LocalDateTime lastViewTime;

    @Schema(description = "最后下载时间", example = "2025-01-09T15:45:00")
    private LocalDateTime lastDownloadTime;

    @Schema(description = "最后分享时间", example = "2025-01-09T14:20:00")
    private LocalDateTime lastShareTime;

    @Schema(description = "统计日期", example = "2025-01-09T00:00:00")
    private LocalDateTime statisticsDate;

    @Schema(description = "统计类型", example = "DAILY", allowableValues = {"DAILY", "WEEKLY", "MONTHLY", "YEARLY", "TOTAL"})
    private String statisticsType;

    @Schema(description = "数据来源", example = "SYSTEM", allowableValues = {"SYSTEM", "MANUAL", "IMPORT", "SYNC"})
    private String dataSource;

    @Schema(description = "扩展统计数据", example = "{\"mobileViews\": 45, \"desktopViews\": 105}")
    private String extendedData;

    @Schema(description = "备注", example = "统计数据更新")
    private String remarks;

    @Schema(description = "更新原因", example = "数据同步更新")
    private String updateReason;

    /**
     * 验证更新数据
     */
    public boolean isValid() {
        // 验证计数字段不为负数
        if (viewCount != null && viewCount < 0) return false;
        if (downloadCount != null && downloadCount < 0) return false;
        if (shareCount != null && shareCount < 0) return false;
        if (favoriteCount != null && favoriteCount < 0) return false;
        if (commentCount != null && commentCount < 0) return false;
        if (likeCount != null && likeCount < 0) return false;
        if (ratingCount != null && ratingCount < 0) return false;
        if (uniqueVisitors != null && uniqueVisitors < 0) return false;
        if (totalViewDuration != null && totalViewDuration < 0) return false;
        
        // 验证评分范围
        if (averageRating != null && (averageRating < 0 || averageRating > 5)) return false;
        
        // 验证比率范围
        if (bounceRate != null && (bounceRate < 0 || bounceRate > 1)) return false;
        if (conversionRate != null && (conversionRate < 0 || conversionRate > 1)) return false;
        
        return true;
    }

    /**
     * 是否有计数更新
     */
    public boolean hasCountUpdate() {
        return viewCount != null || downloadCount != null || shareCount != null ||
               favoriteCount != null || commentCount != null || likeCount != null ||
               ratingCount != null || uniqueVisitors != null;
    }

    /**
     * 是否有评分更新
     */
    public boolean hasRatingUpdate() {
        return ratingCount != null || averageRating != null || totalRating != null;
    }

    /**
     * 是否有时长更新
     */
    public boolean hasDurationUpdate() {
        return totalViewDuration != null || averageViewDuration != null;
    }

    /**
     * 是否有比率更新
     */
    public boolean hasRateUpdate() {
        return bounceRate != null || conversionRate != null;
    }

    /**
     * 是否有时间更新
     */
    public boolean hasTimeUpdate() {
        return lastViewTime != null || lastDownloadTime != null || 
               lastShareTime != null || statisticsDate != null;
    }

    /**
     * 增加查看次数
     */
    public static DocumentStatisticsUpdateDTO incrementViewCount(Long currentCount) {
        DocumentStatisticsUpdateDTO dto = new DocumentStatisticsUpdateDTO();
        dto.setViewCount(currentCount + 1);
        dto.setLastViewTime(LocalDateTime.now());
        dto.setUpdateReason("查看次数增加");
        return dto;
    }

    /**
     * 增加下载次数
     */
    public static DocumentStatisticsUpdateDTO incrementDownloadCount(Long currentCount) {
        DocumentStatisticsUpdateDTO dto = new DocumentStatisticsUpdateDTO();
        dto.setDownloadCount(currentCount + 1);
        dto.setLastDownloadTime(LocalDateTime.now());
        dto.setUpdateReason("下载次数增加");
        return dto;
    }

    /**
     * 增加分享次数
     */
    public static DocumentStatisticsUpdateDTO incrementShareCount(Long currentCount) {
        DocumentStatisticsUpdateDTO dto = new DocumentStatisticsUpdateDTO();
        dto.setShareCount(currentCount + 1);
        dto.setLastShareTime(LocalDateTime.now());
        dto.setUpdateReason("分享次数增加");
        return dto;
    }

    /**
     * 更新评分统计
     */
    public static DocumentStatisticsUpdateDTO updateRatingStatistics(Long ratingCount, Double totalRating, Double averageRating) {
        DocumentStatisticsUpdateDTO dto = new DocumentStatisticsUpdateDTO();
        dto.setRatingCount(ratingCount);
        dto.setTotalRating(totalRating);
        dto.setAverageRating(averageRating);
        dto.setUpdateReason("评分统计更新");
        return dto;
    }

    /**
     * 批量更新计数
     */
    public static DocumentStatisticsUpdateDTO batchUpdateCounts(Long viewCount, Long downloadCount, 
                                                              Long shareCount, Long favoriteCount) {
        DocumentStatisticsUpdateDTO dto = new DocumentStatisticsUpdateDTO();
        dto.setViewCount(viewCount);
        dto.setDownloadCount(downloadCount);
        dto.setShareCount(shareCount);
        dto.setFavoriteCount(favoriteCount);
        dto.setUpdateReason("批量统计更新");
        return dto;
    }

    /**
     * 获取更新摘要
     */
    public String getUpdateSummary() {
        StringBuilder summary = new StringBuilder();
        
        if (hasCountUpdate()) {
            summary.append("计数数据已更新; ");
        }
        
        if (hasRatingUpdate()) {
            summary.append("评分统计已更新; ");
        }
        
        if (hasDurationUpdate()) {
            summary.append("时长统计已更新; ");
        }
        
        if (hasRateUpdate()) {
            summary.append("比率统计已更新; ");
        }
        
        if (hasTimeUpdate()) {
            summary.append("时间信息已更新; ");
        }
        
        return summary.length() > 0 ? summary.toString() : "无更新";
    }

    /**
     * 计算总互动次数
     */
    public Long calculateTotalInteractions() {
        long total = 0;
        if (viewCount != null) total += viewCount;
        if (downloadCount != null) total += downloadCount;
        if (shareCount != null) total += shareCount;
        if (favoriteCount != null) total += favoriteCount;
        if (commentCount != null) total += commentCount;
        if (likeCount != null) total += likeCount;
        return total;
    }

    /**
     * 重新计算平均评分
     */
    public void recalculateAverageRating() {
        if (ratingCount != null && ratingCount > 0 && totalRating != null) {
            averageRating = totalRating / ratingCount;
        }
    }

    /**
     * 重新计算平均访问时长
     */
    public void recalculateAverageViewDuration() {
        if (viewCount != null && viewCount > 0 && totalViewDuration != null) {
            averageViewDuration = totalViewDuration.doubleValue() / viewCount;
        }
    }

    /**
     * 重新计算转化率
     */
    public void recalculateConversionRate() {
        if (viewCount != null && viewCount > 0) {
            long conversions = 0;
            if (downloadCount != null) conversions += downloadCount;
            if (shareCount != null) conversions += shareCount;
            if (favoriteCount != null) conversions += favoriteCount;

            conversionRate = ((double) conversions) / viewCount;
        }
    }

    /**
     * 是否为重要更新
     */
    public boolean isSignificantUpdate() {
        return hasCountUpdate() || hasRatingUpdate() || hasRateUpdate();
    }

    /**
     * 计算更新重要性分数
     */
    public double calculateUpdateImportance() {
        double score = 0.0;
        
        // 计数更新权重 40%
        if (hasCountUpdate()) score += 0.4;
        
        // 评分更新权重 30%
        if (hasRatingUpdate()) score += 0.3;
        
        // 比率更新权重 20%
        if (hasRateUpdate()) score += 0.2;
        
        // 时长更新权重 10%
        if (hasDurationUpdate()) score += 0.1;
        
        return Math.min(score, 1.0);
    }
}
